home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2003 August / MW 8 2003 CD1.iso / Inside Macworld / Product News / gimp-1.2.4.sit / gimp-1.2.4 / app / app_procs.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-04-03  |  21.1 KB  |  845 lines

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  */
  18. #include "config.h"
  19.  
  20. #include <signal.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #ifdef HAVE_SYS_PARAM_H
  25. #include <sys/param.h>
  26. #endif
  27. #include <sys/types.h>
  28. #ifdef HAVE_DIRENT_H
  29. #include <dirent.h>
  30. #endif
  31. #ifdef HAVE_UNISTD_H
  32. #include <unistd.h>
  33. #endif
  34.  
  35. #ifdef G_OS_WIN32
  36. #include <process.h>        /* For _getpid() */
  37. #endif
  38.  
  39. #include <gtk/gtk.h>
  40.  
  41. #include "libgimp/gimpfeatures.h"
  42. #include "libgimp/gimpenv.h"
  43.  
  44. #include "apptypes.h"
  45.  
  46. #include "appenv.h"
  47. #include "app_procs.h"
  48. #include "batch.h"
  49. #include "brush_select.h"
  50. #include "color_transfer.h"
  51. #include "curves.h"
  52. #include "colormaps.h"
  53. #include "context_manager.h"
  54. #include "devices.h"
  55. #include "errorconsole.h"
  56. #include "fileops.h"
  57. #include "gdisplay.h"
  58. #include "gdisplay_ops.h"
  59. #include "gimpbrushlist.h"
  60. #include "gimprc.h"
  61. #include "gimpparasite.h"
  62. #include "gimpset.h"
  63. #include "gimpui.h"
  64. #include "global_edit.h"
  65. #include "gradient_select.h"
  66. #include "gradient.h"
  67. #include "gximage.h"
  68. #include "hue_saturation.h"
  69. #include "image_render.h"
  70. #include "interface.h"
  71. #include "internal_procs.h"
  72. #include "lc_dialog.h"
  73. #include "levels.h"
  74. #include "menus.h"
  75. #include "paint_funcs.h"
  76. #include "palette.h"
  77. #include "pattern_select.h"
  78. #include "patterns.h"
  79. #include "plug_in.h"
  80. #include "module_db.h"
  81. #include "procedural_db.h"
  82. #include "session.h"
  83. #include "temp_buf.h"
  84. #include "tile_swap.h"
  85. #include "tips_dialog.h"
  86. #include "tools.h"
  87. #include "undo.h"
  88. #include "unitrc.h"
  89. #include "xcf.h"
  90. #include "errors.h"
  91. #include "docindex.h"
  92. #include "colormap_dialog.h"
  93.  
  94. #ifdef DISPLAY_FILTERS
  95. #include "gdisplay_color.h"
  96. #endif /* DISPLAY_FILTERS */
  97.  
  98. #include "color_notebook.h"
  99. #include "color_select.h"
  100. #include "gimpparasite.h"
  101.  
  102. #include "libgimp/gimplimits.h"
  103. #include "libgimp/gimpintl.h"
  104.  
  105. #define LOGO_WIDTH_MIN  300
  106. #define LOGO_HEIGHT_MIN 110
  107. #define AUTHORS "Spencer Kimball & Peter Mattis"
  108.  
  109. #define SHOW_NEVER 0
  110. #define SHOW_LATER 1
  111. #define SHOW_NOW   2
  112.  
  113. /*  Function prototype for affirmation dialog when exiting application  */
  114. static void      really_quit_dialog                   (void);
  115. static void      make_initialization_status_window    (void);
  116. static void      destroy_initialization_status_window (void);
  117. static gboolean  splash_logo_load                     (GtkWidget *window);
  118. static gboolean  splash_logo_load_size                (GtkWidget *window);
  119. static void      splash_logo_draw                     (GtkWidget *widget);
  120. static void      splash_text_draw                     (GtkWidget *widget);
  121. static void      splash_logo_expose                   (GtkWidget *widget);
  122. static void      toast_old_temp_files                 (void);
  123.  
  124.  
  125. static gboolean is_app_exit_finish_done = FALSE;
  126. gboolean        we_are_exiting          = FALSE;
  127.  
  128. static GtkWidget *logo_area   = NULL;
  129. static GdkPixmap *logo_pixmap = NULL;
  130. static gint logo_width        = 0;
  131. static gint logo_height       = 0;
  132. static gint logo_area_width   = 0;
  133. static gint logo_area_height  = 0;
  134. static gint show_logo         = SHOW_NEVER;
  135. static gint max_label_length  = 64;
  136.  
  137.  
  138. void
  139. gimp_init (gint    gimp_argc,
  140.        gchar **gimp_argv)
  141. {
  142.   /* Initialize the application */
  143.   app_init ();
  144.  
  145.   /* Parse the rest of the command line arguments as images to load */
  146.   if (gimp_argc > 0)
  147.     while (gimp_argc--)
  148.       {
  149.     if (*gimp_argv)
  150.       file_open (*gimp_argv, *gimp_argv);
  151.     gimp_argv++;
  152.       }
  153.  
  154.   batch_init ();
  155.  
  156.   /* Handle showing dialogs with gdk_quit_adds here  */
  157.   if (!no_interface && show_tips)
  158.     tips_dialog_create ();
  159. }
  160.  
  161. static gboolean
  162. splash_logo_load_size (GtkWidget *window)
  163. {
  164.   gchar buf[1024];
  165.   FILE *fp;
  166.  
  167.   if (logo_pixmap)
  168.     return TRUE;
  169.  
  170.   g_snprintf (buf, sizeof(buf), "%s" G_DIR_SEPARATOR_S "gimp_splash.ppm",
  171.           gimp_data_directory ());
  172.  
  173.   fp = fopen (buf, "rb");
  174.   if (!fp)
  175.     return FALSE;
  176.  
  177.   fgets (buf, sizeof (buf), fp);
  178.   if (strcmp (buf, "P6\n") != 0)
  179.     {
  180.       fclose (fp);
  181.       return FALSE;
  182.     }
  183.  
  184.   fgets (buf, sizeof (buf), fp);
  185.   fgets (buf, sizeof (buf), fp);
  186.   sscanf (buf, "%d %d", &logo_width, &logo_height);
  187.  
  188.   fclose (fp);
  189.  
  190.   return TRUE;
  191. }
  192.  
  193. static gboolean
  194. splash_logo_load (GtkWidget *window)
  195. {
  196.   GtkWidget *preview;
  197.   GdkGC *gc;
  198.   gchar   buf[1024];
  199.   guchar *pixelrow;
  200.   FILE *fp;
  201.   gint count;
  202.   gint i;
  203.  
  204.   if (logo_pixmap)
  205.     return TRUE;
  206.  
  207.   g_snprintf (buf, sizeof(buf), "%s" G_DIR_SEPARATOR_S "gimp_splash.ppm",
  208.           gimp_data_directory ());
  209.  
  210.   fp = fopen (buf, "rb");
  211.   if (!fp)
  212.     return FALSE;
  213.  
  214.   fgets (buf, sizeof (buf), fp);
  215.   if (strcmp (buf, "P6\n") != 0)
  216.     {
  217.       fclose (fp);
  218.       return FALSE;
  219.     }
  220.  
  221.   fgets (buf, sizeof (buf), fp);
  222.   fgets (buf, sizeof (buf), fp);
  223.   sscanf (buf, "%d %d", &logo_width, &logo_height);
  224.  
  225.   fgets (buf, sizeof (buf), fp);
  226.   if (strcmp (buf, "255\n") != 0)
  227.     {
  228.       fclose (fp);
  229.       return FALSE;
  230.     }
  231.  
  232.   preview = gtk_preview_new (GTK_PREVIEW_COLOR);
  233.   gtk_preview_size (GTK_PREVIEW (preview), logo_width, logo_height);
  234.   pixelrow = g_new (guchar, logo_width * 3);
  235.  
  236.   for (i = 0; i < logo_height; i++)
  237.     {
  238.       count = fread (pixelrow, sizeof (unsigned char), logo_width * 3, fp);
  239.       if (count != (logo_width * 3))
  240.     {
  241.       gtk_object_sink (GTK_OBJECT (preview));
  242.       g_free (pixelrow);
  243.       fclose (fp);
  244.       return FALSE;
  245.     }
  246.       gtk_preview_draw_row (GTK_PREVIEW (preview), pixelrow, 0, i, logo_width);
  247.     }
  248.  
  249.   gtk_widget_realize (window);
  250.   logo_pixmap = gdk_pixmap_new (window->window, logo_width, logo_height,
  251.                 gtk_preview_get_visual ()->depth);
  252.   gc = gdk_gc_new (logo_pixmap);
  253.   gtk_preview_put (GTK_PREVIEW (preview),
  254.            logo_pixmap, gc,
  255.            0, 0, 0, 0, logo_width, logo_height);
  256.   gdk_gc_destroy (gc);
  257.  
  258.   gtk_object_sink (GTK_OBJECT (preview));
  259.   g_free (pixelrow);
  260.  
  261.   fclose (fp);
  262.  
  263.   return TRUE;
  264. }
  265.  
  266. static void
  267. splash_text_draw (GtkWidget *widget)
  268. {
  269.   GdkFont *font;
  270.  
  271.   /* this is a font, provide only one single font definition */
  272.   font = gdk_font_load (_("-*-helvetica-bold-r-normal--*-140-*-*-*-*-*-*"));
  273.   if (!font)
  274.     {
  275.       GtkStyle *style = gtk_widget_get_style (widget);
  276.       font = style->font;
  277.       gdk_font_ref (font);
  278.     }
  279.   
  280.   gdk_draw_string (widget->window,
  281.            font,
  282.            widget->style->fg_gc[GTK_STATE_NORMAL],
  283.            ((logo_area_width - gdk_string_width (font,  _("The GIMP"))) / 2),
  284.            (0.25 * logo_area_height),
  285.            _("The GIMP"));
  286.  
  287.   gdk_font_unref (font);
  288.   
  289.   /* this is a fontset, e.g. multiple comma-separated font definitions */
  290.   font = gdk_fontset_load (_("-*-helvetica-bold-r-normal--*-120-*-*-*-*-*-*,*"));
  291.   if (!font)
  292.     {
  293.       GtkStyle *style = gtk_widget_get_style (widget);
  294.       font = style->font;
  295.       gdk_font_ref (font);
  296.     }
  297.  
  298.   gdk_draw_string (widget->window,
  299.            font,
  300.            widget->style->fg_gc[GTK_STATE_NORMAL],
  301.            ((logo_area_width - gdk_string_width (font, GIMP_VERSION)) / 2),
  302.            (0.45 * logo_area_height),
  303.            GIMP_VERSION);
  304.   gdk_draw_string (widget->window,
  305.            font,
  306.            widget->style->fg_gc[GTK_STATE_NORMAL],
  307.            ((logo_area_width - gdk_string_width (font, _("brought to you by"))) / 2),
  308.            (0.65 * logo_area_height),
  309.            _("brought to you by"));
  310.   gdk_draw_string (widget->window,
  311.            font,
  312.            widget->style->fg_gc[GTK_STATE_NORMAL],
  313.            ((logo_area_width - gdk_string_width (font, AUTHORS)) / 2),
  314.            (0.80 * logo_area_height),
  315.            AUTHORS);
  316.  
  317.   gdk_font_unref (font);
  318. }
  319.  
  320. static void
  321. splash_logo_draw (GtkWidget *widget)
  322. {
  323.   gdk_draw_pixmap (widget->window,
  324.            widget->style->black_gc,
  325.            logo_pixmap,
  326.            0, 0,
  327.            ((logo_area_width - logo_width) / 2),
  328.            ((logo_area_height - logo_height) / 2),
  329.            logo_width, logo_height);
  330. }
  331.  
  332. static void
  333. splash_logo_expose (GtkWidget *widget)
  334. {
  335.   switch (show_logo)
  336.     {
  337.     case SHOW_NEVER:
  338.     case SHOW_LATER:
  339.       splash_text_draw (widget);
  340.       break;
  341.     case SHOW_NOW:
  342.       splash_logo_draw (widget);
  343.       break;
  344.     }
  345. }
  346.  
  347. static GtkWidget *win_initstatus = NULL;
  348. static GtkWidget *label1 = NULL;
  349. static GtkWidget *label2 = NULL;
  350. static GtkWidget *pbar   = NULL;
  351.  
  352. static void
  353. destroy_initialization_status_window (void)
  354. {
  355.   if (win_initstatus)
  356.     {
  357.       gtk_widget_destroy (win_initstatus);
  358.  
  359.       if (logo_pixmap != NULL)
  360.     gdk_pixmap_unref (logo_pixmap);
  361.  
  362.       logo_pixmap = NULL;
  363.       win_initstatus = label1 = label2 = pbar = logo_area = NULL;
  364.     }
  365. }
  366.  
  367. static void
  368. make_initialization_status_window (void)
  369. {
  370.   GtkWidget *vbox;
  371.   GtkWidget *logo_hbox;
  372.   GtkStyle  *style;
  373.  
  374.   if (no_interface || no_splash)
  375.     return;
  376.  
  377.   win_initstatus = gtk_window_new (GTK_WINDOW_DIALOG);
  378.  
  379.   gtk_window_set_title (GTK_WINDOW (win_initstatus), _("GIMP Startup"));
  380.   gtk_window_set_wmclass (GTK_WINDOW (win_initstatus), "gimp_startup", "Gimp");
  381.   gtk_window_set_position (GTK_WINDOW (win_initstatus), GTK_WIN_POS_CENTER);
  382.   gtk_window_set_policy (GTK_WINDOW (win_initstatus), FALSE, FALSE, FALSE);
  383.  
  384.   gtk_signal_connect (GTK_OBJECT (win_initstatus), "delete_event",
  385.               GTK_SIGNAL_FUNC (gtk_true),
  386.               NULL);
  387.  
  388.   gimp_dialog_set_icon (GTK_WINDOW (win_initstatus));
  389.  
  390.   if (no_splash_image == FALSE &&
  391.       splash_logo_load_size (win_initstatus))
  392.     {
  393.       show_logo = SHOW_LATER;
  394.     }
  395.  
  396.   vbox = gtk_vbox_new (FALSE, 4);
  397.   gtk_container_add (GTK_CONTAINER (win_initstatus), vbox);
  398.  
  399.   logo_hbox = gtk_hbox_new (FALSE, 0);
  400.   gtk_box_pack_start (GTK_BOX (vbox), logo_hbox, FALSE, TRUE, 0);
  401.  
  402.   logo_area = gtk_drawing_area_new ();
  403.  
  404.   gtk_signal_connect (GTK_OBJECT (logo_area), "expose_event",
  405.               GTK_SIGNAL_FUNC (splash_logo_expose),
  406.               NULL);
  407.  
  408.   logo_area_width  = MAX (logo_width, LOGO_WIDTH_MIN);
  409.   logo_area_height = MAX (logo_height, LOGO_HEIGHT_MIN);
  410.  
  411.   gtk_drawing_area_size (GTK_DRAWING_AREA (logo_area),
  412.              logo_area_width, logo_area_height);
  413.   gtk_box_pack_start (GTK_BOX(logo_hbox), logo_area, TRUE, FALSE, 0);
  414.  
  415.   label1 = gtk_label_new ("");
  416.   gtk_box_pack_start_defaults (GTK_BOX (vbox), label1);
  417.   label2 = gtk_label_new ("");
  418.   gtk_box_pack_start_defaults (GTK_BOX (vbox), label2);
  419.  
  420.   pbar = gtk_progress_bar_new ();
  421.   gtk_box_pack_start_defaults (GTK_BOX (vbox), pbar);
  422.  
  423.   gtk_widget_show (vbox);
  424.   gtk_widget_show (logo_hbox);
  425.   gtk_widget_show (logo_area);
  426.   gtk_widget_show (label1);
  427.   gtk_widget_show (label2);
  428.   gtk_widget_show (pbar);
  429.  
  430.   gtk_widget_show (win_initstatus);
  431.  
  432.   /*  This is a hack: we try to compute a good guess for the maximum 
  433.    *  number of charcters that will fit into the splash-screen using 
  434.    *  the default_font
  435.    */
  436.   style = gtk_widget_get_style (win_initstatus);
  437.   max_label_length = (0.8 * (gfloat) strlen (AUTHORS) *
  438.               ((gfloat) logo_area_width /
  439.                (gfloat) gdk_string_width (style->font, AUTHORS)));
  440. }
  441.  
  442. void
  443. app_init_update_status (gchar *label1val,
  444.                 gchar *label2val,
  445.                 float  pct_progress)
  446. {
  447.   gchar *temp;
  448.  
  449.   if (!no_interface && !no_splash && win_initstatus)
  450.     {
  451.       if (label1val && strcmp (label1val, GTK_LABEL (label1)->label))
  452.     gtk_label_set_text (GTK_LABEL (label1), label1val);
  453.  
  454.       if (label2val && strcmp (label2val, GTK_LABEL (label2)->label))
  455.     {
  456.       while (strlen (label2val) > max_label_length)
  457.         {
  458.           temp = strchr (label2val, G_DIR_SEPARATOR);
  459.           if (temp == NULL)  /* for sanity */
  460.         break;
  461.           temp++;
  462.           label2val = temp;
  463.         }
  464.  
  465.       gtk_label_set_text (GTK_LABEL (label2), label2val);
  466.     }
  467.  
  468.       if (pct_progress >= 0.0 && pct_progress <= 1.0 && 
  469.       gtk_progress_get_current_percentage (&(GTK_PROGRESS_BAR (pbar)->progress)) != pct_progress)
  470.     /*
  471.      GTK_PROGRESS_BAR(pbar)->percentage != pct_progress)
  472.     */
  473.     {
  474.       gtk_progress_bar_update (GTK_PROGRESS_BAR (pbar), pct_progress);
  475.     }
  476.  
  477.       while (gtk_events_pending ())
  478.     gtk_main_iteration ();
  479.  
  480.       /* We sync here to make sure things get drawn before continuing,
  481.        * is the improved look worth the time? I'm not sure...
  482.        */
  483.       gdk_flush ();
  484.     }
  485. }
  486.  
  487. /* #define RESET_BAR() app_init_update_status("", "", 0) */
  488. #define RESET_BAR()
  489.  
  490. void
  491. app_init (void)
  492. {
  493.   gchar *filename;
  494.   gchar *path;
  495.  
  496.   /*  parse the systemwide gtkrc  */
  497.   filename = gimp_gtkrc ();
  498.  
  499.   if (be_verbose)
  500.     g_print (_("parsing \"%s\"\n"), filename);
  501.  
  502.   gtk_rc_parse (filename);
  503.  
  504.   /*  parse the user gtkrc  */
  505.   filename = gimp_personal_rc_file ("gtkrc");
  506.  
  507.   if (be_verbose)
  508.     g_print (_("parsing \"%s\"\n"), filename);
  509.  
  510.   gtk_rc_parse (filename);
  511.  
  512.   g_free (filename);
  513.  
  514.   if (parse_buffers_init ())
  515.     {
  516.       parse_unitrc ();   /*  this needs to be done before gimprc loading  */
  517.       parse_gimprc ();   /*  parse the local GIMP configuration file      */
  518.     }
  519.  
  520.   if (!no_interface)
  521.     get_standard_colormaps ();
  522.  
  523.   make_initialization_status_window ();
  524.  
  525.   if (!no_interface && !no_splash && win_initstatus)
  526.     splash_text_draw (logo_area);
  527.  
  528.   /* Create the context of all existing images */
  529.   image_context = gimp_set_new (GIMP_TYPE_IMAGE, TRUE);
  530.  
  531.   /*  Initialize the context system before loading any data  */
  532.   context_manager_init ();
  533.  
  534.   /*  Initialize the procedural database
  535.    *    We need to do this first because any of the init
  536.    *    procedures might install or query it as needed.
  537.    */
  538.   procedural_db_init ();
  539.   RESET_BAR();
  540.   internal_procs_init ();
  541.  
  542. #ifdef DISPLAY_FILTERS
  543.   color_display_init ();
  544. #endif /* DISPLAY_FILTERS */
  545.  
  546.   RESET_BAR();
  547.   if (always_restore_session)
  548.     restore_session = TRUE;
  549.  
  550.   /* make sure the monitor resolution is valid */
  551.   if (monitor_xres < GIMP_MIN_RESOLUTION ||
  552.       monitor_yres < GIMP_MIN_RESOLUTION)
  553.     {
  554.       gdisplay_xserver_resolution (&monitor_xres, &monitor_yres);
  555.       using_xserver_resolution = TRUE;
  556.     }
  557.  
  558.   /* Now we are ready to draw the splash-screen-image to the start-up window */
  559.   if (no_interface == FALSE)
  560.     {
  561.       if (no_splash_image == FALSE && show_logo &&
  562.       splash_logo_load (win_initstatus))
  563.     {
  564.       show_logo = SHOW_NOW;
  565.       splash_logo_draw (logo_area);
  566.         }
  567.     }
  568.  
  569. #ifdef G_OS_WIN32
  570.   /* Do this already here on Win32 */
  571.   if (no_interface == FALSE)
  572.     {
  573.       /*  FIXME: This needs to go in preferences  */
  574.       message_handler = MESSAGE_BOX;
  575.     }
  576. #endif
  577.  
  578.  
  579.   RESET_BAR();
  580.   file_ops_pre_init ();    /*  pre-initialize the file types  */
  581.   RESET_BAR();
  582.   xcf_init ();             /*  initialize the xcf file format routines */
  583.  
  584.   app_init_update_status (_("Looking for data files"), _("Parasites"), 0.00);
  585.   gimp_init_parasites ();          /*  initialize  the global parasite table  */
  586.   app_init_update_status (NULL, _("Brushes"), 0.20);
  587.   brushes_init (no_data);          /*  initialize the list of gimp brushes    */
  588.   app_init_update_status (NULL, _("Patterns"), 0.40);
  589.   patterns_init (no_data);         /*  initialize the list of gimp patterns   */
  590.   app_init_update_status (NULL, _("Palettes"), 0.60);
  591.   palettes_init (no_data);         /*  initialize the list of gimp palettes   */
  592.   app_init_update_status (NULL, _("Gradients"), 0.80);
  593.   gradients_init (no_data);        /*  initialize the list of gimp gradients  */
  594.   app_init_update_status (NULL, NULL, 1.00);
  595.  
  596.   plug_in_init ();           /*  initialize the plug in structures  */
  597.   module_db_init ();         /*  load any modules we need           */
  598.   RESET_BAR();
  599.   file_ops_post_init ();     /*  post-initialize the file types     */
  600.  
  601.   menus_reorder_plugins ();  /*  beautify some menus                */
  602.  
  603.   /* Add the swap file  */
  604.   if (swap_path == NULL)
  605.     swap_path = g_get_tmp_dir ();
  606.  
  607.   toast_old_temp_files ();
  608.   path = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "gimpswap.%lu",
  609.               swap_path, (unsigned long) getpid ());
  610.   tile_swap_add (path, NULL, NULL);
  611.   g_free (path);
  612.  
  613.   destroy_initialization_status_window ();
  614.  
  615.   /*  Things to do only if there is an interface  */
  616.   if (no_interface == FALSE)
  617.     {
  618.       devices_init ();
  619.       session_init ();
  620.       create_toolbox ();
  621.  
  622.       /*  Fill the "last opened" menu items with the first last_opened_size
  623.        *  elements of the docindex
  624.        */
  625.       {
  626.     FILE   *fp;
  627.     gchar **filenames = g_new (gchar *, last_opened_size);
  628.     gint    i;
  629.  
  630.     if ((fp = document_index_parse_init ()))
  631.       {
  632.         /*  read the filenames...  */
  633.         for (i = 0; i < last_opened_size; i++)
  634.           if ((filenames[i] = document_index_parse_line (fp)) == NULL)
  635.         break;
  636.  
  637.         /*  ...and add them in reverse order  */
  638.         for (--i; i >= 0; i--)
  639.           {
  640.         menus_last_opened_add (filenames[i]);
  641.         g_free (filenames[i]);
  642.           }
  643.  
  644.         fclose (fp);
  645.       }
  646.     g_free (filenames);
  647.       }
  648.  
  649.       gximage_init ();
  650.       render_setup (transparency_type, transparency_size);
  651.       tool_options_dialog_new ();
  652.  
  653.       /*  EEK: force signal emission  */
  654.       if (gimp_context_get_tool (gimp_context_get_user ()) == RECT_SELECT)
  655.     {
  656.       gimp_context_tool_changed (gimp_context_get_user ());
  657.     }
  658.       else
  659.     {
  660.       gimp_context_set_tool (gimp_context_get_user (), RECT_SELECT);
  661.     }
  662. #ifndef G_OS_WIN32
  663.       /*  FIXME: This needs to go in preferences  */
  664.       message_handler = MESSAGE_BOX;
  665. #endif
  666.     }
  667.  
  668.   /* check if a swap file can be created */
  669.   if (tile_swap_test () == FALSE)
  670.     {
  671.       g_message (_("Unable to open a test swap file.  Please check the\n"
  672.                    "location and permissions of the swap directory defined\n"
  673.                    "in your Preferences (currently '%s')."), swap_path);
  674.     }
  675.  
  676.   color_transfer_init ();
  677.   paint_funcs_setup ();
  678.  
  679.   /* register internal color selectors */
  680.   color_select_init ();
  681.  
  682.   if (no_interface == FALSE)
  683.     {
  684.       devices_restore ();
  685.       session_restore ();
  686.     }
  687. }
  688.  
  689. int
  690. app_exit_finish_done (void)
  691. {
  692.   return is_app_exit_finish_done;
  693. }
  694.  
  695. void
  696. app_exit_finish (void)
  697. {
  698.   if (app_exit_finish_done ())
  699.     return;
  700.   is_app_exit_finish_done = TRUE;
  701.  
  702.   message_handler = CONSOLE;
  703.   we_are_exiting = TRUE;
  704.  
  705.   /*  do this here before brushes and patterns are freed  */
  706.   if (!no_interface)
  707.     device_status_free ();
  708.  
  709.   module_db_free ();
  710.   lc_dialog_free ();
  711.   gdisplays_delete ();
  712.   global_edit_free ();
  713.   named_buffers_free ();
  714.   swapping_free ();
  715.   brush_dialog_free ();
  716.   brushes_free ();
  717.   pattern_dialog_free ();
  718.   patterns_free ();
  719.   palette_dialog_free ();
  720.   palettes_free ();
  721.   gradient_dialog_free ();
  722.   gradients_free ();
  723.   context_manager_free ();
  724.   hue_saturation_free ();
  725.   curves_free ();
  726.   levels_free ();
  727.   paint_funcs_free ();
  728.   plug_in_kill ();
  729.   procedural_db_free ();
  730.   error_console_free ();
  731.   menus_quit ();
  732.   tile_swap_exit ();
  733.   save_unitrc ();
  734.   gimp_parasiterc_save ();
  735.  
  736.   /*  Things to do only if there is an interface  */
  737.   if (!no_interface)
  738.     {
  739.       toolbox_free ();
  740.       document_index_free ();
  741.       gximage_free ();
  742.       render_free ();
  743.       tool_options_dialog_free ();
  744.       save_sessionrc ();
  745.     }
  746.  
  747.   /*  There used to be gtk_main_quit() here, but there's a chance 
  748.    *  that gtk_main() was never called before we reach this point. --Sven  
  749.    */
  750.   gtk_exit (0);   
  751. }
  752.  
  753. void
  754. app_exit (gboolean kill_it)
  755. {
  756.   /*  If it's the user's perogative, and there are dirty images  */
  757.   if (!kill_it && gdisplays_dirty () && !no_interface)
  758.     really_quit_dialog ();
  759.   else
  760.     app_exit_finish ();
  761. }
  762.  
  763. /*************************************************
  764.  *   Routines to query exiting the application   *
  765.  *************************************************/
  766.  
  767. static void
  768. really_quit_callback (GtkWidget *button,
  769.               gboolean   quit,
  770.               gpointer   data)
  771. {
  772.   if (quit)
  773.     {
  774.       app_exit_finish ();
  775.     }
  776.   else
  777.     {
  778.       menus_set_sensitive ("<Toolbox>/File/Quit", TRUE);
  779.       menus_set_sensitive ("<Image>/File/Quit", TRUE);
  780.     }
  781. }
  782.  
  783. static void
  784. really_quit_dialog (void)
  785. {
  786.   GtkWidget *dialog;
  787.  
  788.   menus_set_sensitive ("<Toolbox>/File/Quit", FALSE);
  789.   menus_set_sensitive ("<Image>/File/Quit", FALSE);
  790.  
  791.   dialog = gimp_query_boolean_box (_("Really Quit?"),
  792.                    gimp_standard_help_func,
  793.                    "dialogs/really_quit.html",
  794.                    TRUE,
  795.                    _("Some files unsaved.\n\nQuit the GIMP?"),
  796.                    _("Quit"), _("Cancel"),
  797.                    NULL, NULL,
  798.                    really_quit_callback,
  799.                    NULL);
  800.  
  801.   gtk_widget_show (dialog);
  802. }
  803.  
  804. static void
  805. toast_old_temp_files (void)
  806. {
  807.   DIR *dir;
  808.   struct dirent *entry;
  809.   GString *filename = g_string_new ("");
  810.  
  811.   dir = opendir (swap_path);
  812.  
  813.   if (!dir)
  814.     return;
  815.  
  816.   while ((entry = readdir (dir)) != NULL)
  817.     if (!strncmp (entry->d_name, "gimpswap.", 9))
  818.       {
  819.         /* don't try to kill swap files of running processes
  820.          * yes, I know they might not all be gimp processes, and when you
  821.          * unlink, it's refcounted, but lets not confuse the user by
  822.          * "where did my disk space go?" cause the filename is gone
  823.          * if the kill succeeds, and there running process isn't gimp
  824.          * we'll probably get it the next time around
  825.          */
  826.  
  827. #ifndef G_OS_WIN32
  828.     gint pid = atoi (entry->d_name + 9);
  829.     if (kill (pid, 0))
  830. #endif
  831.       {
  832.         /*  On Windows, you can't remove open files anyhow,
  833.          *  so no harm trying.
  834.          */
  835.         g_string_sprintf (filename, "%s" G_DIR_SEPARATOR_S "%s",
  836.                   swap_path, entry->d_name);
  837.         unlink (filename->str);
  838.       }
  839.       }
  840.  
  841.   closedir (dir);
  842.   
  843.   g_string_free (filename, TRUE);
  844. }
  845.